//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_spi(SotoInternal) import SotoCore

extension DirectoryServiceData {
    // MARK: Enums

    public enum AccessDeniedReason: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case dataDisabled = "DATA_DISABLED"
        case directoryAuth = "DIRECTORY_AUTH"
        case iamAuth = "IAM_AUTH"
        public var description: String { return self.rawValue }
    }

    public enum DirectoryUnavailableReason: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case directoryResourcesExceeded = "DIRECTORY_RESOURCES_EXCEEDED"
        case directoryTimeout = "DIRECTORY_TIMEOUT"
        case invalidDirectoryState = "INVALID_DIRECTORY_STATE"
        case noDiskSpace = "NO_DISK_SPACE"
        case trustAuthFailure = "TRUST_AUTH_FAILURE"
        public var description: String { return self.rawValue }
    }

    public enum GroupScope: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case builtinLocal = "BuiltinLocal"
        case domainLocal = "DomainLocal"
        case global = "Global"
        case universal = "Universal"
        public var description: String { return self.rawValue }
    }

    public enum GroupType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case distribution = "Distribution"
        case security = "Security"
        public var description: String { return self.rawValue }
    }

    public enum MemberType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case computer = "COMPUTER"
        case group = "GROUP"
        case user = "USER"
        public var description: String { return self.rawValue }
    }

    public enum UpdateType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case add = "ADD"
        case remove = "REMOVE"
        case replace = "REPLACE"
        public var description: String { return self.rawValue }
    }

    public enum ValidationExceptionReason: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case attributeExists = "ATTRIBUTE_EXISTS"
        case duplicateAttribute = "DUPLICATE_ATTRIBUTE"
        case invalidAttributeForGroup = "INVALID_ATTRIBUTE_FOR_GROUP"
        case invalidAttributeForModify = "INVALID_ATTRIBUTE_FOR_MODIFY"
        case invalidAttributeForSearch = "INVALID_ATTRIBUTE_FOR_SEARCH"
        case invalidAttributeForUser = "INVALID_ATTRIBUTE_FOR_USER"
        case invalidAttributeName = "INVALID_ATTRIBUTE_NAME"
        case invalidAttributeValue = "INVALID_ATTRIBUTE_VALUE"
        case invalidDirectoryType = "INVALID_DIRECTORY_TYPE"
        case invalidNextToken = "INVALID_NEXT_TOKEN"
        case invalidRealm = "INVALID_REALM"
        case invalidSecondaryRegion = "INVALID_SECONDARY_REGION"
        case ldapSizeLimitExceeded = "LDAP_SIZE_LIMIT_EXCEEDED"
        case ldapUnsupportedOperation = "LDAP_UNSUPPORTED_OPERATION"
        case missingAttribute = "MISSING_ATTRIBUTE"
        public var description: String { return self.rawValue }
    }

    public enum AttributeValue: AWSEncodableShape & AWSDecodableShape, Sendable {
        ///  Indicates that the attribute type value is a boolean. For example:   "BOOL": true
        case bool(Bool)
        ///  Indicates that the attribute type value is a number. For example:   "N": "16"
        case n(Int64)
        ///  Indicates that the attribute type value is a string. For example:   "S": "S Group"
        case s(String)
        ///  Indicates that the attribute type value is a string set. For example:   "SS": ["sample_service_class/host.sample.com:1234/sample_service_name_1", "sample_service_class/host.sample.com:1234/sample_service_name_2"]
        case ss([String])

        public init(from decoder: Decoder) throws {
            let container = try decoder.container(keyedBy: CodingKeys.self)
            guard container.allKeys.count == 1, let key = container.allKeys.first else {
                let context = DecodingError.Context(
                    codingPath: container.codingPath,
                    debugDescription: "Expected exactly one key, but got \(container.allKeys.count)"
                )
                throw DecodingError.dataCorrupted(context)
            }
            switch key {
            case .bool:
                let value = try container.decode(Bool.self, forKey: .bool)
                self = .bool(value)
            case .n:
                let value = try container.decode(Int64.self, forKey: .n)
                self = .n(value)
            case .s:
                let value = try container.decode(String.self, forKey: .s)
                self = .s(value)
            case .ss:
                let value = try container.decode([String].self, forKey: .ss)
                self = .ss(value)
            }
        }

        public func encode(to encoder: Encoder) throws {
            var container = encoder.container(keyedBy: CodingKeys.self)
            switch self {
            case .bool(let value):
                try container.encode(value, forKey: .bool)
            case .n(let value):
                try container.encode(value, forKey: .n)
            case .s(let value):
                try container.encode(value, forKey: .s)
            case .ss(let value):
                try container.encode(value, forKey: .ss)
            }
        }

        public func validate(name: String) throws {
            switch self {
            case .s(let value):
                try self.validate(value, name: "s", parent: name, max: 1024)
                try self.validate(value, name: "s", parent: name, min: 1)
            case .ss(let value):
                try value.forEach {
                    try validate($0, name: "ss[]", parent: name, max: 1024)
                    try validate($0, name: "ss[]", parent: name, min: 1)
                }
                try self.validate(value, name: "ss", parent: name, max: 25)
            default:
                break
            }
        }

        private enum CodingKeys: String, CodingKey {
            case bool = "BOOL"
            case n = "N"
            case s = "S"
            case ss = "SS"
        }
    }

    // MARK: Shapes

    public struct AccessDeniedException: AWSErrorShape {
        public let message: String?
        ///  Reason the request was unauthorized.
        public let reason: AccessDeniedReason?

        @inlinable
        public init(message: String? = nil, reason: AccessDeniedReason? = nil) {
            self.message = message
            self.reason = reason
        }

        private enum CodingKeys: String, CodingKey {
            case message = "Message"
            case reason = "Reason"
        }
    }

    public struct AddGroupMemberRequest: AWSEncodableShape {
        ///  A unique and case-sensitive identifier that you provide to make sure the idempotency of the request, so multiple identical calls have the same effect as one single call.  A client token is valid for 8 hours after the first request that uses it completes. After 8 hours, any request with the same client token is treated as a new request. If the request succeeds, any future uses of that token will be idempotent for another 8 hours.  If you submit a request with the same client token but change one of the other parameters within the 8-hour idempotency window, Directory Service Data returns an ConflictException.   This parameter is optional when using the CLI or SDK.
        public let clientToken: String?
        ///  The identifier (ID) of the directory that's associated with the group.
        public let directoryId: String
        ///  The name of the group.
        public let groupName: String
        ///  The SAMAccountName of the user, group, or computer to add as a group member.
        public let memberName: String
        ///  The domain name that's associated with the group member. This parameter is required only when adding a member outside of your Managed Microsoft AD domain to a group inside of your Managed Microsoft AD domain. This parameter defaults to the Managed Microsoft AD domain.   This parameter is case insensitive.
        public let memberRealm: String?

        @inlinable
        public init(clientToken: String? = AddGroupMemberRequest.idempotencyToken(), directoryId: String, groupName: String, memberName: String, memberRealm: String? = nil) {
            self.clientToken = clientToken
            self.directoryId = directoryId
            self.groupName = groupName
            self.memberName = memberName
            self.memberRealm = memberRealm
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encodeIfPresent(self.clientToken, forKey: .clientToken)
            request.encodeQuery(self.directoryId, key: "DirectoryId")
            try container.encode(self.groupName, forKey: .groupName)
            try container.encode(self.memberName, forKey: .memberName)
            try container.encodeIfPresent(self.memberRealm, forKey: .memberRealm)
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 128)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: "^[\\x00-\\x7F]+$")
            try self.validate(self.directoryId, name: "directoryId", parent: name, pattern: "^d-[0-9a-f]{10}$")
            try self.validate(self.groupName, name: "groupName", parent: name, max: 64)
            try self.validate(self.groupName, name: "groupName", parent: name, min: 1)
            try self.validate(self.groupName, name: "groupName", parent: name, pattern: "^[^:;|=+\"*?<>/\\\\,\\[\\]@]+$")
            try self.validate(self.memberName, name: "memberName", parent: name, max: 63)
            try self.validate(self.memberName, name: "memberName", parent: name, min: 1)
            try self.validate(self.memberName, name: "memberName", parent: name, pattern: "^[^:;|=+\"*?<>/\\\\,\\[\\]@]+$")
            try self.validate(self.memberRealm, name: "memberRealm", parent: name, max: 255)
            try self.validate(self.memberRealm, name: "memberRealm", parent: name, min: 1)
            try self.validate(self.memberRealm, name: "memberRealm", parent: name, pattern: "^([a-zA-Z0-9]+[\\\\.-])+([a-zA-Z0-9])+[.]?$")
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "ClientToken"
            case groupName = "GroupName"
            case memberName = "MemberName"
            case memberRealm = "MemberRealm"
        }
    }

    public struct AddGroupMemberResult: AWSDecodableShape {
        public init() {}
    }

    public struct CreateGroupRequest: AWSEncodableShape {
        ///  A unique and case-sensitive identifier that you provide to make sure the idempotency of the request, so multiple identical calls have the same effect as one single call.  A client token is valid for 8 hours after the first request that uses it completes. After 8 hours, any request with the same client token is treated as a new request. If the request succeeds, any future uses of that token will be idempotent for another 8 hours.  If you submit a request with the same client token but change one of the other parameters within the 8-hour idempotency window, Directory Service Data returns an ConflictException.   This parameter is optional when using the CLI or SDK.
        public let clientToken: String?
        ///  The identifier (ID) of the directory that's associated with the group.
        public let directoryId: String
        ///  The scope of the AD group. For details, see Active Directory security group scope.
        public let groupScope: GroupScope?
        ///  The AD group type. For details, see Active Directory security group type.
        public let groupType: GroupType?
        ///  An expression that defines one or more attributes with the data type and value of each attribute.
        public let otherAttributes: [String: AttributeValue]?
        ///  The name of the group.
        public let samAccountName: String

        @inlinable
        public init(clientToken: String? = CreateGroupRequest.idempotencyToken(), directoryId: String, groupScope: GroupScope? = nil, groupType: GroupType? = nil, otherAttributes: [String: AttributeValue]? = nil, samAccountName: String) {
            self.clientToken = clientToken
            self.directoryId = directoryId
            self.groupScope = groupScope
            self.groupType = groupType
            self.otherAttributes = otherAttributes
            self.samAccountName = samAccountName
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encodeIfPresent(self.clientToken, forKey: .clientToken)
            request.encodeQuery(self.directoryId, key: "DirectoryId")
            try container.encodeIfPresent(self.groupScope, forKey: .groupScope)
            try container.encodeIfPresent(self.groupType, forKey: .groupType)
            try container.encodeIfPresent(self.otherAttributes, forKey: .otherAttributes)
            try container.encode(self.samAccountName, forKey: .samAccountName)
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 128)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: "^[\\x00-\\x7F]+$")
            try self.validate(self.directoryId, name: "directoryId", parent: name, pattern: "^d-[0-9a-f]{10}$")
            try self.otherAttributes?.forEach {
                try validate($0.key, name: "otherAttributes.key", parent: name, max: 63)
                try validate($0.key, name: "otherAttributes.key", parent: name, min: 1)
                try validate($0.key, name: "otherAttributes.key", parent: name, pattern: "^[A-Za-z*][A-Za-z-*]*$")
                try $0.value.validate(name: "\(name).otherAttributes[\"\($0.key)\"]")
            }
            try self.validate(self.otherAttributes, name: "otherAttributes", parent: name, max: 25)
            try self.validate(self.otherAttributes, name: "otherAttributes", parent: name, min: 1)
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, max: 64)
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, min: 1)
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, pattern: "^[^:;|=+\"*?<>/\\\\,\\[\\]@]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "ClientToken"
            case groupScope = "GroupScope"
            case groupType = "GroupType"
            case otherAttributes = "OtherAttributes"
            case samAccountName = "SAMAccountName"
        }
    }

    public struct CreateGroupResult: AWSDecodableShape {
        ///  The identifier (ID) of the directory that's associated with the group.
        public let directoryId: String?
        ///  The name of the group.
        public let samAccountName: String?
        ///  The unique security identifier (SID) of the group.
        public let sid: String?

        @inlinable
        public init(directoryId: String? = nil, samAccountName: String? = nil, sid: String? = nil) {
            self.directoryId = directoryId
            self.samAccountName = samAccountName
            self.sid = sid
        }

        private enum CodingKeys: String, CodingKey {
            case directoryId = "DirectoryId"
            case samAccountName = "SAMAccountName"
            case sid = "SID"
        }
    }

    public struct CreateUserRequest: AWSEncodableShape {
        ///  A unique and case-sensitive identifier that you provide to make sure the idempotency of the request, so multiple identical calls have the same effect as one single call.  A client token is valid for 8 hours after the first request that uses it completes. After 8 hours, any request with the same client token is treated as a new request. If the request succeeds, any future uses of that token will be idempotent for another 8 hours.  If you submit a request with the same client token but change one of the other parameters within the 8-hour idempotency window, Directory Service Data returns an ConflictException.   This parameter is optional when using the CLI or SDK.
        public let clientToken: String?
        ///  The identifier (ID) of the directory that’s associated with the user.
        public let directoryId: String
        ///  The email address of the user.
        public let emailAddress: String?
        ///  The first name of the user.
        public let givenName: String?
        ///  An expression that defines one or more attribute names with the data type and value of each attribute. A key is an attribute name, and the value is a list of maps. For a list of supported attributes, see Directory Service Data Attributes.   Attribute names are case insensitive.
        public let otherAttributes: [String: AttributeValue]?
        ///  The name of the user.
        public let samAccountName: String
        ///  The last name of the user.
        public let surname: String?

        @inlinable
        public init(clientToken: String? = CreateUserRequest.idempotencyToken(), directoryId: String, emailAddress: String? = nil, givenName: String? = nil, otherAttributes: [String: AttributeValue]? = nil, samAccountName: String, surname: String? = nil) {
            self.clientToken = clientToken
            self.directoryId = directoryId
            self.emailAddress = emailAddress
            self.givenName = givenName
            self.otherAttributes = otherAttributes
            self.samAccountName = samAccountName
            self.surname = surname
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encodeIfPresent(self.clientToken, forKey: .clientToken)
            request.encodeQuery(self.directoryId, key: "DirectoryId")
            try container.encodeIfPresent(self.emailAddress, forKey: .emailAddress)
            try container.encodeIfPresent(self.givenName, forKey: .givenName)
            try container.encodeIfPresent(self.otherAttributes, forKey: .otherAttributes)
            try container.encode(self.samAccountName, forKey: .samAccountName)
            try container.encodeIfPresent(self.surname, forKey: .surname)
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 128)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: "^[\\x00-\\x7F]+$")
            try self.validate(self.directoryId, name: "directoryId", parent: name, pattern: "^d-[0-9a-f]{10}$")
            try self.validate(self.emailAddress, name: "emailAddress", parent: name, max: 256)
            try self.validate(self.emailAddress, name: "emailAddress", parent: name, min: 1)
            try self.validate(self.givenName, name: "givenName", parent: name, max: 64)
            try self.validate(self.givenName, name: "givenName", parent: name, min: 1)
            try self.otherAttributes?.forEach {
                try validate($0.key, name: "otherAttributes.key", parent: name, max: 63)
                try validate($0.key, name: "otherAttributes.key", parent: name, min: 1)
                try validate($0.key, name: "otherAttributes.key", parent: name, pattern: "^[A-Za-z*][A-Za-z-*]*$")
                try $0.value.validate(name: "\(name).otherAttributes[\"\($0.key)\"]")
            }
            try self.validate(self.otherAttributes, name: "otherAttributes", parent: name, max: 25)
            try self.validate(self.otherAttributes, name: "otherAttributes", parent: name, min: 1)
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, max: 20)
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, min: 1)
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, pattern: "^[\\w\\-.]+$")
            try self.validate(self.surname, name: "surname", parent: name, max: 64)
            try self.validate(self.surname, name: "surname", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "ClientToken"
            case emailAddress = "EmailAddress"
            case givenName = "GivenName"
            case otherAttributes = "OtherAttributes"
            case samAccountName = "SAMAccountName"
            case surname = "Surname"
        }
    }

    public struct CreateUserResult: AWSDecodableShape {
        ///  The identifier (ID) of the directory where the address block is added.
        public let directoryId: String?
        ///  The name of the user.
        public let samAccountName: String?
        ///  The unique security identifier (SID) of the user.
        public let sid: String?

        @inlinable
        public init(directoryId: String? = nil, samAccountName: String? = nil, sid: String? = nil) {
            self.directoryId = directoryId
            self.samAccountName = samAccountName
            self.sid = sid
        }

        private enum CodingKeys: String, CodingKey {
            case directoryId = "DirectoryId"
            case samAccountName = "SAMAccountName"
            case sid = "SID"
        }
    }

    public struct DeleteGroupRequest: AWSEncodableShape {
        ///  A unique and case-sensitive identifier that you provide to make sure the idempotency of the request, so multiple identical calls have the same effect as one single call.  A client token is valid for 8 hours after the first request that uses it completes. After 8 hours, any request with the same client token is treated as a new request. If the request succeeds, any future uses of that token will be idempotent for another 8 hours.  If you submit a request with the same client token but change one of the other parameters within the 8-hour idempotency window, Directory Service Data returns an ConflictException.   This parameter is optional when using the CLI or SDK.
        public let clientToken: String?
        ///  The identifier (ID) of the directory that's associated with the group.
        public let directoryId: String
        ///  The name of the group.
        public let samAccountName: String

        @inlinable
        public init(clientToken: String? = DeleteGroupRequest.idempotencyToken(), directoryId: String, samAccountName: String) {
            self.clientToken = clientToken
            self.directoryId = directoryId
            self.samAccountName = samAccountName
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encodeIfPresent(self.clientToken, forKey: .clientToken)
            request.encodeQuery(self.directoryId, key: "DirectoryId")
            try container.encode(self.samAccountName, forKey: .samAccountName)
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 128)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: "^[\\x00-\\x7F]+$")
            try self.validate(self.directoryId, name: "directoryId", parent: name, pattern: "^d-[0-9a-f]{10}$")
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, max: 64)
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, min: 1)
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, pattern: "^[^:;|=+\"*?<>/\\\\,\\[\\]@]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "ClientToken"
            case samAccountName = "SAMAccountName"
        }
    }

    public struct DeleteGroupResult: AWSDecodableShape {
        public init() {}
    }

    public struct DeleteUserRequest: AWSEncodableShape {
        ///  A unique and case-sensitive identifier that you provide to make sure the idempotency of the request, so multiple identical calls have the same effect as one single call.  A client token is valid for 8 hours after the first request that uses it completes. After 8 hours, any request with the same client token is treated as a new request. If the request succeeds, any future uses of that token will be idempotent for another 8 hours.  If you submit a request with the same client token but change one of the other parameters within the 8-hour idempotency window, Directory Service Data returns an ConflictException.   This parameter is optional when using the CLI or SDK.
        public let clientToken: String?
        ///  The identifier (ID) of the directory that's associated with the user.
        public let directoryId: String
        ///  The name of the user.
        public let samAccountName: String

        @inlinable
        public init(clientToken: String? = DeleteUserRequest.idempotencyToken(), directoryId: String, samAccountName: String) {
            self.clientToken = clientToken
            self.directoryId = directoryId
            self.samAccountName = samAccountName
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encodeIfPresent(self.clientToken, forKey: .clientToken)
            request.encodeQuery(self.directoryId, key: "DirectoryId")
            try container.encode(self.samAccountName, forKey: .samAccountName)
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 128)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: "^[\\x00-\\x7F]+$")
            try self.validate(self.directoryId, name: "directoryId", parent: name, pattern: "^d-[0-9a-f]{10}$")
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, max: 20)
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, min: 1)
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, pattern: "^[\\w\\-.]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "ClientToken"
            case samAccountName = "SAMAccountName"
        }
    }

    public struct DeleteUserResult: AWSDecodableShape {
        public init() {}
    }

    public struct DescribeGroupRequest: AWSEncodableShape {
        /// The Identifier (ID) of the directory associated with the group.
        public let directoryId: String
        ///  One or more attributes to be returned for the group. For a list of supported attributes, see Directory Service Data Attributes.
        public let otherAttributes: [String]?
        ///  The domain name that's associated with the group.   This parameter is optional, so you can return groups outside of your Managed Microsoft AD domain. When no value is defined, only your Managed Microsoft AD groups are returned.  This value is case insensitive.
        public let realm: String?
        ///  The name of the group.
        public let samAccountName: String

        @inlinable
        public init(directoryId: String, otherAttributes: [String]? = nil, realm: String? = nil, samAccountName: String) {
            self.directoryId = directoryId
            self.otherAttributes = otherAttributes
            self.realm = realm
            self.samAccountName = samAccountName
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.directoryId, key: "DirectoryId")
            try container.encodeIfPresent(self.otherAttributes, forKey: .otherAttributes)
            try container.encodeIfPresent(self.realm, forKey: .realm)
            try container.encode(self.samAccountName, forKey: .samAccountName)
        }

        public func validate(name: String) throws {
            try self.validate(self.directoryId, name: "directoryId", parent: name, pattern: "^d-[0-9a-f]{10}$")
            try self.otherAttributes?.forEach {
                try validate($0, name: "otherAttributes[]", parent: name, max: 63)
                try validate($0, name: "otherAttributes[]", parent: name, min: 1)
                try validate($0, name: "otherAttributes[]", parent: name, pattern: "^[A-Za-z*][A-Za-z-*]*$")
            }
            try self.validate(self.otherAttributes, name: "otherAttributes", parent: name, max: 25)
            try self.validate(self.otherAttributes, name: "otherAttributes", parent: name, min: 1)
            try self.validate(self.realm, name: "realm", parent: name, max: 255)
            try self.validate(self.realm, name: "realm", parent: name, min: 1)
            try self.validate(self.realm, name: "realm", parent: name, pattern: "^([a-zA-Z0-9]+[\\\\.-])+([a-zA-Z0-9])+[.]?$")
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, max: 64)
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, min: 1)
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, pattern: "^[^:;|=+\"*?<>/\\\\,\\[\\]@]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case otherAttributes = "OtherAttributes"
            case realm = "Realm"
            case samAccountName = "SAMAccountName"
        }
    }

    public struct DescribeGroupResult: AWSDecodableShape {
        ///  The identifier (ID) of the directory that's associated with the group.
        public let directoryId: String?
        ///  The distinguished name of the object.
        public let distinguishedName: String?
        ///  The scope of the AD group. For details, see Active Directory security groups.
        public let groupScope: GroupScope?
        ///  The AD group type. For details, see Active Directory security group type.
        public let groupType: GroupType?
        ///  The attribute values that are returned for the attribute names that are included in the request.
        public let otherAttributes: [String: AttributeValue]?
        ///  The domain name that's associated with the group.
        public let realm: String?
        ///  The name of the group.
        public let samAccountName: String?
        ///  The unique security identifier (SID) of the group.
        public let sid: String?

        @inlinable
        public init(directoryId: String? = nil, distinguishedName: String? = nil, groupScope: GroupScope? = nil, groupType: GroupType? = nil, otherAttributes: [String: AttributeValue]? = nil, realm: String? = nil, samAccountName: String? = nil, sid: String? = nil) {
            self.directoryId = directoryId
            self.distinguishedName = distinguishedName
            self.groupScope = groupScope
            self.groupType = groupType
            self.otherAttributes = otherAttributes
            self.realm = realm
            self.samAccountName = samAccountName
            self.sid = sid
        }

        private enum CodingKeys: String, CodingKey {
            case directoryId = "DirectoryId"
            case distinguishedName = "DistinguishedName"
            case groupScope = "GroupScope"
            case groupType = "GroupType"
            case otherAttributes = "OtherAttributes"
            case realm = "Realm"
            case samAccountName = "SAMAccountName"
            case sid = "SID"
        }
    }

    public struct DescribeUserRequest: AWSEncodableShape {
        ///  The identifier (ID) of the directory that's associated with the user.
        public let directoryId: String
        ///  One or more attribute names to be returned for the user. A key is an attribute name, and the value is a list of maps. For a list of supported attributes, see Directory Service Data Attributes.
        public let otherAttributes: [String]?
        ///  The domain name that's associated with the user.   This parameter is optional, so you can return users outside your Managed Microsoft AD domain. When no value is defined, only your Managed Microsoft AD users are returned.  This value is case insensitive.
        public let realm: String?
        ///  The name of the user.
        public let samAccountName: String

        @inlinable
        public init(directoryId: String, otherAttributes: [String]? = nil, realm: String? = nil, samAccountName: String) {
            self.directoryId = directoryId
            self.otherAttributes = otherAttributes
            self.realm = realm
            self.samAccountName = samAccountName
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.directoryId, key: "DirectoryId")
            try container.encodeIfPresent(self.otherAttributes, forKey: .otherAttributes)
            try container.encodeIfPresent(self.realm, forKey: .realm)
            try container.encode(self.samAccountName, forKey: .samAccountName)
        }

        public func validate(name: String) throws {
            try self.validate(self.directoryId, name: "directoryId", parent: name, pattern: "^d-[0-9a-f]{10}$")
            try self.otherAttributes?.forEach {
                try validate($0, name: "otherAttributes[]", parent: name, max: 63)
                try validate($0, name: "otherAttributes[]", parent: name, min: 1)
                try validate($0, name: "otherAttributes[]", parent: name, pattern: "^[A-Za-z*][A-Za-z-*]*$")
            }
            try self.validate(self.otherAttributes, name: "otherAttributes", parent: name, max: 25)
            try self.validate(self.otherAttributes, name: "otherAttributes", parent: name, min: 1)
            try self.validate(self.realm, name: "realm", parent: name, max: 255)
            try self.validate(self.realm, name: "realm", parent: name, min: 1)
            try self.validate(self.realm, name: "realm", parent: name, pattern: "^([a-zA-Z0-9]+[\\\\.-])+([a-zA-Z0-9])+[.]?$")
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, max: 20)
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, min: 1)
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, pattern: "^[\\w\\-.]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case otherAttributes = "OtherAttributes"
            case realm = "Realm"
            case samAccountName = "SAMAccountName"
        }
    }

    public struct DescribeUserResult: AWSDecodableShape {
        ///  The identifier (ID) of the directory that's associated with the user.
        public let directoryId: String?
        ///  The distinguished name of the object.
        public let distinguishedName: String?
        ///  The email address of the user.
        public let emailAddress: String?
        ///  Indicates whether the user account is active.
        public let enabled: Bool?
        ///  The first name of the user.
        public let givenName: String?
        ///  The attribute values that are returned for the attribute names that are included in the request.   Attribute names are case insensitive.
        public let otherAttributes: [String: AttributeValue]?
        ///  The domain name that's associated with the user.
        public let realm: String?
        ///  The name of the user.
        public let samAccountName: String?
        ///  The unique security identifier (SID) of the user.
        public let sid: String?
        ///  The last name of the user.
        public let surname: String?
        ///  The UPN that is an Internet-style login name for a user and is based on the Internet standard RFC 822. The UPN is shorter than the distinguished name and easier to remember.
        public let userPrincipalName: String?

        @inlinable
        public init(directoryId: String? = nil, distinguishedName: String? = nil, emailAddress: String? = nil, enabled: Bool? = nil, givenName: String? = nil, otherAttributes: [String: AttributeValue]? = nil, realm: String? = nil, samAccountName: String? = nil, sid: String? = nil, surname: String? = nil, userPrincipalName: String? = nil) {
            self.directoryId = directoryId
            self.distinguishedName = distinguishedName
            self.emailAddress = emailAddress
            self.enabled = enabled
            self.givenName = givenName
            self.otherAttributes = otherAttributes
            self.realm = realm
            self.samAccountName = samAccountName
            self.sid = sid
            self.surname = surname
            self.userPrincipalName = userPrincipalName
        }

        private enum CodingKeys: String, CodingKey {
            case directoryId = "DirectoryId"
            case distinguishedName = "DistinguishedName"
            case emailAddress = "EmailAddress"
            case enabled = "Enabled"
            case givenName = "GivenName"
            case otherAttributes = "OtherAttributes"
            case realm = "Realm"
            case samAccountName = "SAMAccountName"
            case sid = "SID"
            case surname = "Surname"
            case userPrincipalName = "UserPrincipalName"
        }
    }

    public struct DirectoryUnavailableException: AWSErrorShape {
        public let message: String?
        ///  Reason the request failed for the specified directory.
        public let reason: DirectoryUnavailableReason?

        @inlinable
        public init(message: String? = nil, reason: DirectoryUnavailableReason? = nil) {
            self.message = message
            self.reason = reason
        }

        private enum CodingKeys: String, CodingKey {
            case message = "Message"
            case reason = "Reason"
        }
    }

    public struct DisableUserRequest: AWSEncodableShape {
        ///  A unique and case-sensitive identifier that you provide to make sure the idempotency of the request, so multiple identical calls have the same effect as one single call.  A client token is valid for 8 hours after the first request that uses it completes. After 8 hours, any request with the same client token is treated as a new request. If the request succeeds, any future uses of that token will be idempotent for another 8 hours.  If you submit a request with the same client token but change one of the other parameters within the 8-hour idempotency window, Directory Service Data returns an ConflictException.   This parameter is optional when using the CLI or SDK.
        public let clientToken: String?
        ///  The identifier (ID) of the directory that's associated with the user.
        public let directoryId: String
        ///  The name of the user.
        public let samAccountName: String

        @inlinable
        public init(clientToken: String? = DisableUserRequest.idempotencyToken(), directoryId: String, samAccountName: String) {
            self.clientToken = clientToken
            self.directoryId = directoryId
            self.samAccountName = samAccountName
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encodeIfPresent(self.clientToken, forKey: .clientToken)
            request.encodeQuery(self.directoryId, key: "DirectoryId")
            try container.encode(self.samAccountName, forKey: .samAccountName)
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 128)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: "^[\\x00-\\x7F]+$")
            try self.validate(self.directoryId, name: "directoryId", parent: name, pattern: "^d-[0-9a-f]{10}$")
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, max: 20)
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, min: 1)
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, pattern: "^[\\w\\-.]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "ClientToken"
            case samAccountName = "SAMAccountName"
        }
    }

    public struct DisableUserResult: AWSDecodableShape {
        public init() {}
    }

    public struct Group: AWSDecodableShape {
        /// The distinguished name of the object.
        public let distinguishedName: String?
        ///  The scope of the AD group. For details, see Active Directory security groups
        public let groupScope: GroupScope?
        ///  The AD group type. For details, see Active Directory security group type.
        public let groupType: GroupType?
        ///  An expression of one or more attributes, data types, and the values of a group.
        public let otherAttributes: [String: AttributeValue]?
        ///  The name of the group.
        public let samAccountName: String
        ///  The unique security identifier (SID) of the group.
        public let sid: String?

        @inlinable
        public init(distinguishedName: String? = nil, groupScope: GroupScope? = nil, groupType: GroupType? = nil, otherAttributes: [String: AttributeValue]? = nil, samAccountName: String, sid: String? = nil) {
            self.distinguishedName = distinguishedName
            self.groupScope = groupScope
            self.groupType = groupType
            self.otherAttributes = otherAttributes
            self.samAccountName = samAccountName
            self.sid = sid
        }

        private enum CodingKeys: String, CodingKey {
            case distinguishedName = "DistinguishedName"
            case groupScope = "GroupScope"
            case groupType = "GroupType"
            case otherAttributes = "OtherAttributes"
            case samAccountName = "SAMAccountName"
            case sid = "SID"
        }
    }

    public struct GroupSummary: AWSDecodableShape {
        /// The scope of the AD group. For details, see Active Directory security groups.
        public let groupScope: GroupScope
        /// The AD group type. For details, see Active Directory security group type.
        public let groupType: GroupType
        /// The name of the group.
        public let samAccountName: String
        /// The unique security identifier (SID) of the group.
        public let sid: String

        @inlinable
        public init(groupScope: GroupScope, groupType: GroupType, samAccountName: String, sid: String) {
            self.groupScope = groupScope
            self.groupType = groupType
            self.samAccountName = samAccountName
            self.sid = sid
        }

        private enum CodingKeys: String, CodingKey {
            case groupScope = "GroupScope"
            case groupType = "GroupType"
            case samAccountName = "SAMAccountName"
            case sid = "SID"
        }
    }

    public struct ListGroupMembersRequest: AWSEncodableShape {
        ///  The identifier (ID) of the directory that's associated with the group.
        public let directoryId: String
        ///  The maximum number of results to be returned per request.
        public let maxResults: Int?
        ///  The domain name that's associated with the group member. This parameter defaults to the Managed Microsoft AD domain.   This parameter is optional and case insensitive.
        public let memberRealm: String?
        /// An encoded paging token for paginated calls that can be passed back to retrieve the next page.
        public let nextToken: String?
        ///  The domain name that's associated with the group.   This parameter is optional, so you can return members from a group outside of your Managed Microsoft AD domain. When no value is defined, only members of your Managed Microsoft AD groups are returned.  This value is case insensitive.
        public let realm: String?
        ///  The name of the group.
        public let samAccountName: String

        @inlinable
        public init(directoryId: String, maxResults: Int? = nil, memberRealm: String? = nil, nextToken: String? = nil, realm: String? = nil, samAccountName: String) {
            self.directoryId = directoryId
            self.maxResults = maxResults
            self.memberRealm = memberRealm
            self.nextToken = nextToken
            self.realm = realm
            self.samAccountName = samAccountName
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.directoryId, key: "DirectoryId")
            try container.encodeIfPresent(self.maxResults, forKey: .maxResults)
            try container.encodeIfPresent(self.memberRealm, forKey: .memberRealm)
            try container.encodeIfPresent(self.nextToken, forKey: .nextToken)
            try container.encodeIfPresent(self.realm, forKey: .realm)
            try container.encode(self.samAccountName, forKey: .samAccountName)
        }

        public func validate(name: String) throws {
            try self.validate(self.directoryId, name: "directoryId", parent: name, pattern: "^d-[0-9a-f]{10}$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 250)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.memberRealm, name: "memberRealm", parent: name, max: 255)
            try self.validate(self.memberRealm, name: "memberRealm", parent: name, min: 1)
            try self.validate(self.memberRealm, name: "memberRealm", parent: name, pattern: "^([a-zA-Z0-9]+[\\\\.-])+([a-zA-Z0-9])+[.]?$")
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 6144)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.realm, name: "realm", parent: name, max: 255)
            try self.validate(self.realm, name: "realm", parent: name, min: 1)
            try self.validate(self.realm, name: "realm", parent: name, pattern: "^([a-zA-Z0-9]+[\\\\.-])+([a-zA-Z0-9])+[.]?$")
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, max: 64)
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, min: 1)
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, pattern: "^[^:;|=+\"*?<>/\\\\,\\[\\]@]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case memberRealm = "MemberRealm"
            case nextToken = "NextToken"
            case realm = "Realm"
            case samAccountName = "SAMAccountName"
        }
    }

    public struct ListGroupMembersResult: AWSDecodableShape {
        /// Identifier (ID) of the directory associated with the group.
        public let directoryId: String?
        ///  The domain name that's associated with the member.
        public let memberRealm: String?
        ///  The member information that the request returns.
        public let members: [Member]?
        ///  An encoded paging token for paginated calls that can be passed back to retrieve the next page.
        public let nextToken: String?
        ///  The domain name that's associated with the group.
        public let realm: String?

        @inlinable
        public init(directoryId: String? = nil, memberRealm: String? = nil, members: [Member]? = nil, nextToken: String? = nil, realm: String? = nil) {
            self.directoryId = directoryId
            self.memberRealm = memberRealm
            self.members = members
            self.nextToken = nextToken
            self.realm = realm
        }

        private enum CodingKeys: String, CodingKey {
            case directoryId = "DirectoryId"
            case memberRealm = "MemberRealm"
            case members = "Members"
            case nextToken = "NextToken"
            case realm = "Realm"
        }
    }

    public struct ListGroupsForMemberRequest: AWSEncodableShape {
        ///  The identifier (ID) of the directory that's associated with the member.
        public let directoryId: String
        ///  The maximum number of results to be returned per request.
        public let maxResults: Int?
        ///  The domain name that's associated with the group member.   This parameter is optional, so you can limit your results to the group members in a specific domain.  This parameter is case insensitive and defaults to Realm
        public let memberRealm: String?
        ///  An encoded paging token for paginated calls that can be passed back to retrieve the next page.
        public let nextToken: String?
        ///  The domain name that's associated with the group.   This parameter is optional, so you can return groups outside of your Managed Microsoft AD domain. When no value is defined, only your Managed Microsoft AD groups are returned.  This value is case insensitive and defaults to your Managed Microsoft AD domain.
        public let realm: String?
        ///  The SAMAccountName of the user, group, or computer that's a member of the group.
        public let samAccountName: String

        @inlinable
        public init(directoryId: String, maxResults: Int? = nil, memberRealm: String? = nil, nextToken: String? = nil, realm: String? = nil, samAccountName: String) {
            self.directoryId = directoryId
            self.maxResults = maxResults
            self.memberRealm = memberRealm
            self.nextToken = nextToken
            self.realm = realm
            self.samAccountName = samAccountName
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.directoryId, key: "DirectoryId")
            try container.encodeIfPresent(self.maxResults, forKey: .maxResults)
            try container.encodeIfPresent(self.memberRealm, forKey: .memberRealm)
            try container.encodeIfPresent(self.nextToken, forKey: .nextToken)
            try container.encodeIfPresent(self.realm, forKey: .realm)
            try container.encode(self.samAccountName, forKey: .samAccountName)
        }

        public func validate(name: String) throws {
            try self.validate(self.directoryId, name: "directoryId", parent: name, pattern: "^d-[0-9a-f]{10}$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 250)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.memberRealm, name: "memberRealm", parent: name, max: 255)
            try self.validate(self.memberRealm, name: "memberRealm", parent: name, min: 1)
            try self.validate(self.memberRealm, name: "memberRealm", parent: name, pattern: "^([a-zA-Z0-9]+[\\\\.-])+([a-zA-Z0-9])+[.]?$")
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 6144)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.realm, name: "realm", parent: name, max: 255)
            try self.validate(self.realm, name: "realm", parent: name, min: 1)
            try self.validate(self.realm, name: "realm", parent: name, pattern: "^([a-zA-Z0-9]+[\\\\.-])+([a-zA-Z0-9])+[.]?$")
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, max: 63)
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, min: 1)
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, pattern: "^[^:;|=+\"*?<>/\\\\,\\[\\]@]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case memberRealm = "MemberRealm"
            case nextToken = "NextToken"
            case realm = "Realm"
            case samAccountName = "SAMAccountName"
        }
    }

    public struct ListGroupsForMemberResult: AWSDecodableShape {
        ///  The identifier (ID) of the directory that's associated with the member.
        public let directoryId: String?
        ///  The group information that the request returns.
        public let groups: [GroupSummary]?
        ///  The domain that's associated with the member.
        public let memberRealm: String?
        ///  An encoded paging token for paginated calls that can be passed back to retrieve the next page.
        public let nextToken: String?
        ///  The domain that's associated with the group.
        public let realm: String?

        @inlinable
        public init(directoryId: String? = nil, groups: [GroupSummary]? = nil, memberRealm: String? = nil, nextToken: String? = nil, realm: String? = nil) {
            self.directoryId = directoryId
            self.groups = groups
            self.memberRealm = memberRealm
            self.nextToken = nextToken
            self.realm = realm
        }

        private enum CodingKeys: String, CodingKey {
            case directoryId = "DirectoryId"
            case groups = "Groups"
            case memberRealm = "MemberRealm"
            case nextToken = "NextToken"
            case realm = "Realm"
        }
    }

    public struct ListGroupsRequest: AWSEncodableShape {
        ///  The identifier (ID) of the directory that's associated with the group.
        public let directoryId: String
        ///  The maximum number of results to be returned per request.
        public let maxResults: Int?
        ///  An encoded paging token for paginated calls that can be passed back to retrieve the next page.
        public let nextToken: String?
        ///  The domain name associated with the directory.   This parameter is optional, so you can return groups outside of your Managed Microsoft AD domain. When no value is defined, only your Managed Microsoft AD groups are returned.  This value is case insensitive.
        public let realm: String?

        @inlinable
        public init(directoryId: String, maxResults: Int? = nil, nextToken: String? = nil, realm: String? = nil) {
            self.directoryId = directoryId
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.realm = realm
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.directoryId, key: "DirectoryId")
            try container.encodeIfPresent(self.maxResults, forKey: .maxResults)
            try container.encodeIfPresent(self.nextToken, forKey: .nextToken)
            try container.encodeIfPresent(self.realm, forKey: .realm)
        }

        public func validate(name: String) throws {
            try self.validate(self.directoryId, name: "directoryId", parent: name, pattern: "^d-[0-9a-f]{10}$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 250)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 6144)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.realm, name: "realm", parent: name, max: 255)
            try self.validate(self.realm, name: "realm", parent: name, min: 1)
            try self.validate(self.realm, name: "realm", parent: name, pattern: "^([a-zA-Z0-9]+[\\\\.-])+([a-zA-Z0-9])+[.]?$")
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case realm = "Realm"
        }
    }

    public struct ListGroupsResult: AWSDecodableShape {
        ///  The identifier (ID) of the directory that's associated with the group.
        public let directoryId: String?
        ///  The group information that the request returns.
        public let groups: [GroupSummary]?
        ///  An encoded paging token for paginated calls that can be passed back to retrieve the next page.
        public let nextToken: String?
        /// The domain name associated with the group.
        public let realm: String?

        @inlinable
        public init(directoryId: String? = nil, groups: [GroupSummary]? = nil, nextToken: String? = nil, realm: String? = nil) {
            self.directoryId = directoryId
            self.groups = groups
            self.nextToken = nextToken
            self.realm = realm
        }

        private enum CodingKeys: String, CodingKey {
            case directoryId = "DirectoryId"
            case groups = "Groups"
            case nextToken = "NextToken"
            case realm = "Realm"
        }
    }

    public struct ListUsersRequest: AWSEncodableShape {
        ///  The identifier (ID) of the directory that's associated with the user.
        public let directoryId: String
        ///  The maximum number of results to be returned per request.
        public let maxResults: Int?
        ///  An encoded paging token for paginated calls that can be passed back to retrieve the next page.
        public let nextToken: String?
        ///  The domain name that's associated with the user.   This parameter is optional, so you can return users outside of your Managed Microsoft AD domain. When no value is defined, only your Managed Microsoft AD users are returned.  This value is case insensitive.
        public let realm: String?

        @inlinable
        public init(directoryId: String, maxResults: Int? = nil, nextToken: String? = nil, realm: String? = nil) {
            self.directoryId = directoryId
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.realm = realm
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.directoryId, key: "DirectoryId")
            try container.encodeIfPresent(self.maxResults, forKey: .maxResults)
            try container.encodeIfPresent(self.nextToken, forKey: .nextToken)
            try container.encodeIfPresent(self.realm, forKey: .realm)
        }

        public func validate(name: String) throws {
            try self.validate(self.directoryId, name: "directoryId", parent: name, pattern: "^d-[0-9a-f]{10}$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 250)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 6144)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.realm, name: "realm", parent: name, max: 255)
            try self.validate(self.realm, name: "realm", parent: name, min: 1)
            try self.validate(self.realm, name: "realm", parent: name, pattern: "^([a-zA-Z0-9]+[\\\\.-])+([a-zA-Z0-9])+[.]?$")
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case realm = "Realm"
        }
    }

    public struct ListUsersResult: AWSDecodableShape {
        ///  The identifier (ID) of the directory that's associated with the user.
        public let directoryId: String?
        ///  An encoded paging token for paginated calls that can be passed back to retrieve the next page.
        public let nextToken: String?
        ///  The domain that's associated with the user.
        public let realm: String?
        ///  The user information that the request returns.
        public let users: [UserSummary]?

        @inlinable
        public init(directoryId: String? = nil, nextToken: String? = nil, realm: String? = nil, users: [UserSummary]? = nil) {
            self.directoryId = directoryId
            self.nextToken = nextToken
            self.realm = realm
            self.users = users
        }

        private enum CodingKeys: String, CodingKey {
            case directoryId = "DirectoryId"
            case nextToken = "NextToken"
            case realm = "Realm"
            case users = "Users"
        }
    }

    public struct Member: AWSDecodableShape {
        ///  The AD type of the member object.
        public let memberType: MemberType
        ///  The name of the group member.
        public let samAccountName: String
        ///  The unique security identifier (SID) of the group member.
        public let sid: String

        @inlinable
        public init(memberType: MemberType, samAccountName: String, sid: String) {
            self.memberType = memberType
            self.samAccountName = samAccountName
            self.sid = sid
        }

        private enum CodingKeys: String, CodingKey {
            case memberType = "MemberType"
            case samAccountName = "SAMAccountName"
            case sid = "SID"
        }
    }

    public struct RemoveGroupMemberRequest: AWSEncodableShape {
        ///  A unique and case-sensitive identifier that you provide to make sure the idempotency of the request, so multiple identical calls have the same effect as one single call.  A client token is valid for 8 hours after the first request that uses it completes. After 8 hours, any request with the same client token is treated as a new request. If the request succeeds, any future uses of that token will be idempotent for another 8 hours.  If you submit a request with the same client token but change one of the other parameters within the 8-hour idempotency window, Directory Service Data returns an ConflictException.   This parameter is optional when using the CLI or SDK.
        public let clientToken: String?
        ///  The identifier (ID) of the directory that's associated with the member.
        public let directoryId: String
        ///  The name of the group.
        public let groupName: String
        ///  The SAMAccountName of the user, group, or computer to remove from the group.
        public let memberName: String
        ///  The domain name that's associated with the group member. This parameter defaults to the Managed Microsoft AD domain.   This parameter is optional and case insensitive.
        public let memberRealm: String?

        @inlinable
        public init(clientToken: String? = RemoveGroupMemberRequest.idempotencyToken(), directoryId: String, groupName: String, memberName: String, memberRealm: String? = nil) {
            self.clientToken = clientToken
            self.directoryId = directoryId
            self.groupName = groupName
            self.memberName = memberName
            self.memberRealm = memberRealm
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encodeIfPresent(self.clientToken, forKey: .clientToken)
            request.encodeQuery(self.directoryId, key: "DirectoryId")
            try container.encode(self.groupName, forKey: .groupName)
            try container.encode(self.memberName, forKey: .memberName)
            try container.encodeIfPresent(self.memberRealm, forKey: .memberRealm)
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 128)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: "^[\\x00-\\x7F]+$")
            try self.validate(self.directoryId, name: "directoryId", parent: name, pattern: "^d-[0-9a-f]{10}$")
            try self.validate(self.groupName, name: "groupName", parent: name, max: 64)
            try self.validate(self.groupName, name: "groupName", parent: name, min: 1)
            try self.validate(self.groupName, name: "groupName", parent: name, pattern: "^[^:;|=+\"*?<>/\\\\,\\[\\]@]+$")
            try self.validate(self.memberName, name: "memberName", parent: name, max: 63)
            try self.validate(self.memberName, name: "memberName", parent: name, min: 1)
            try self.validate(self.memberName, name: "memberName", parent: name, pattern: "^[^:;|=+\"*?<>/\\\\,\\[\\]@]+$")
            try self.validate(self.memberRealm, name: "memberRealm", parent: name, max: 255)
            try self.validate(self.memberRealm, name: "memberRealm", parent: name, min: 1)
            try self.validate(self.memberRealm, name: "memberRealm", parent: name, pattern: "^([a-zA-Z0-9]+[\\\\.-])+([a-zA-Z0-9])+[.]?$")
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "ClientToken"
            case groupName = "GroupName"
            case memberName = "MemberName"
            case memberRealm = "MemberRealm"
        }
    }

    public struct RemoveGroupMemberResult: AWSDecodableShape {
        public init() {}
    }

    public struct SearchGroupsRequest: AWSEncodableShape {
        ///  The identifier (ID) of the directory that's associated with the group.
        public let directoryId: String
        ///  The maximum number of results to be returned per request.
        public let maxResults: Int?
        ///  An encoded paging token for paginated calls that can be passed back to retrieve the next page.
        public let nextToken: String?
        ///  The domain name that's associated with the group.   This parameter is optional, so you can return groups outside of your Managed Microsoft AD domain. When no value is defined, only your Managed Microsoft AD groups are returned.  This value is case insensitive.
        public let realm: String?
        ///  One or more data attributes that are used to search for a group. For a list of supported attributes, see Directory Service Data Attributes.
        public let searchAttributes: [String]
        ///  The attribute value that you want to search for.   Wildcard (*) searches aren't supported. For a list of supported attributes, see Directory Service Data Attributes.
        public let searchString: String

        @inlinable
        public init(directoryId: String, maxResults: Int? = nil, nextToken: String? = nil, realm: String? = nil, searchAttributes: [String], searchString: String) {
            self.directoryId = directoryId
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.realm = realm
            self.searchAttributes = searchAttributes
            self.searchString = searchString
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.directoryId, key: "DirectoryId")
            try container.encodeIfPresent(self.maxResults, forKey: .maxResults)
            try container.encodeIfPresent(self.nextToken, forKey: .nextToken)
            try container.encodeIfPresent(self.realm, forKey: .realm)
            try container.encode(self.searchAttributes, forKey: .searchAttributes)
            try container.encode(self.searchString, forKey: .searchString)
        }

        public func validate(name: String) throws {
            try self.validate(self.directoryId, name: "directoryId", parent: name, pattern: "^d-[0-9a-f]{10}$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 250)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 6144)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.realm, name: "realm", parent: name, max: 255)
            try self.validate(self.realm, name: "realm", parent: name, min: 1)
            try self.validate(self.realm, name: "realm", parent: name, pattern: "^([a-zA-Z0-9]+[\\\\.-])+([a-zA-Z0-9])+[.]?$")
            try self.searchAttributes.forEach {
                try validate($0, name: "searchAttributes[]", parent: name, max: 63)
                try validate($0, name: "searchAttributes[]", parent: name, min: 1)
                try validate($0, name: "searchAttributes[]", parent: name, pattern: "^[A-Za-z*][A-Za-z-*]*$")
            }
            try self.validate(self.searchAttributes, name: "searchAttributes", parent: name, max: 25)
            try self.validate(self.searchAttributes, name: "searchAttributes", parent: name, min: 1)
            try self.validate(self.searchString, name: "searchString", parent: name, max: 64)
            try self.validate(self.searchString, name: "searchString", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case realm = "Realm"
            case searchAttributes = "SearchAttributes"
            case searchString = "SearchString"
        }
    }

    public struct SearchGroupsResult: AWSDecodableShape {
        ///  The identifier (ID) of the directory that's associated with the group.
        public let directoryId: String?
        ///  The group information that the request returns.
        public let groups: [Group]?
        ///  An encoded paging token for paginated calls that can be passed back to retrieve the next page.
        public let nextToken: String?
        ///  The domain that's associated with the group.
        public let realm: String?

        @inlinable
        public init(directoryId: String? = nil, groups: [Group]? = nil, nextToken: String? = nil, realm: String? = nil) {
            self.directoryId = directoryId
            self.groups = groups
            self.nextToken = nextToken
            self.realm = realm
        }

        private enum CodingKeys: String, CodingKey {
            case directoryId = "DirectoryId"
            case groups = "Groups"
            case nextToken = "NextToken"
            case realm = "Realm"
        }
    }

    public struct SearchUsersRequest: AWSEncodableShape {
        ///  The identifier (ID) of the directory that's associated with the user.
        public let directoryId: String
        ///  The maximum number of results to be returned per request.
        public let maxResults: Int?
        ///  An encoded paging token for paginated calls that can be passed back to retrieve the next page.
        public let nextToken: String?
        ///  The domain name that's associated with the user.   This parameter is optional, so you can return users outside of your Managed Microsoft AD domain. When no value is defined, only your Managed Microsoft AD users are returned.  This value is case insensitive.
        public let realm: String?
        ///  One or more data attributes that are used to search for a user. For a list of supported attributes, see Directory Service Data Attributes.
        public let searchAttributes: [String]
        ///  The attribute value that you want to search for.   Wildcard (*) searches aren't supported. For a list of supported attributes, see Directory Service Data Attributes.
        public let searchString: String

        @inlinable
        public init(directoryId: String, maxResults: Int? = nil, nextToken: String? = nil, realm: String? = nil, searchAttributes: [String], searchString: String) {
            self.directoryId = directoryId
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.realm = realm
            self.searchAttributes = searchAttributes
            self.searchString = searchString
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.directoryId, key: "DirectoryId")
            try container.encodeIfPresent(self.maxResults, forKey: .maxResults)
            try container.encodeIfPresent(self.nextToken, forKey: .nextToken)
            try container.encodeIfPresent(self.realm, forKey: .realm)
            try container.encode(self.searchAttributes, forKey: .searchAttributes)
            try container.encode(self.searchString, forKey: .searchString)
        }

        public func validate(name: String) throws {
            try self.validate(self.directoryId, name: "directoryId", parent: name, pattern: "^d-[0-9a-f]{10}$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 250)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 6144)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.realm, name: "realm", parent: name, max: 255)
            try self.validate(self.realm, name: "realm", parent: name, min: 1)
            try self.validate(self.realm, name: "realm", parent: name, pattern: "^([a-zA-Z0-9]+[\\\\.-])+([a-zA-Z0-9])+[.]?$")
            try self.searchAttributes.forEach {
                try validate($0, name: "searchAttributes[]", parent: name, max: 63)
                try validate($0, name: "searchAttributes[]", parent: name, min: 1)
                try validate($0, name: "searchAttributes[]", parent: name, pattern: "^[A-Za-z*][A-Za-z-*]*$")
            }
            try self.validate(self.searchAttributes, name: "searchAttributes", parent: name, max: 25)
            try self.validate(self.searchAttributes, name: "searchAttributes", parent: name, min: 1)
            try self.validate(self.searchString, name: "searchString", parent: name, max: 64)
            try self.validate(self.searchString, name: "searchString", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case realm = "Realm"
            case searchAttributes = "SearchAttributes"
            case searchString = "SearchString"
        }
    }

    public struct SearchUsersResult: AWSDecodableShape {
        ///  The identifier (ID) of the directory where the address block is added.
        public let directoryId: String?
        ///  An encoded paging token for paginated calls that can be passed back to retrieve the next page.
        public let nextToken: String?
        ///  The domain that's associated with the user.
        public let realm: String?
        ///  The user information that the request returns.
        public let users: [User]?

        @inlinable
        public init(directoryId: String? = nil, nextToken: String? = nil, realm: String? = nil, users: [User]? = nil) {
            self.directoryId = directoryId
            self.nextToken = nextToken
            self.realm = realm
            self.users = users
        }

        private enum CodingKeys: String, CodingKey {
            case directoryId = "DirectoryId"
            case nextToken = "NextToken"
            case realm = "Realm"
            case users = "Users"
        }
    }

    public struct ThrottlingException: AWSErrorShape {
        public let message: String
        ///  The recommended amount of seconds to retry after a throttling exception.
        public let retryAfterSeconds: Int?

        @inlinable
        public init(message: String, retryAfterSeconds: Int? = nil) {
            self.message = message
            self.retryAfterSeconds = retryAfterSeconds
        }

        public init(from decoder: Decoder) throws {
            let response = decoder.userInfo[.awsResponse]! as! ResponseDecodingContainer
            let container = try decoder.container(keyedBy: CodingKeys.self)
            self.message = try container.decode(String.self, forKey: .message)
            self.retryAfterSeconds = try response.decodeHeaderIfPresent(Int.self, key: "Retry-After")
        }

        private enum CodingKeys: String, CodingKey {
            case message = "Message"
        }
    }

    public struct UpdateGroupRequest: AWSEncodableShape {
        ///  A unique and case-sensitive identifier that you provide to make sure the idempotency of the request, so multiple identical calls have the same effect as one single call.  A client token is valid for 8 hours after the first request that uses it completes. After 8 hours, any request with the same client token is treated as a new request. If the request succeeds, any future uses of that token will be idempotent for another 8 hours.  If you submit a request with the same client token but change one of the other parameters within the 8-hour idempotency window, Directory Service Data returns an ConflictException.   This parameter is optional when using the CLI or SDK.
        public let clientToken: String?
        ///  The identifier (ID) of the directory that's associated with the group.
        public let directoryId: String
        ///  The scope of the AD group. For details, see Active Directory security groups.
        public let groupScope: GroupScope?
        ///  The AD group type. For details, see Active Directory security group type.
        public let groupType: GroupType?
        ///  An expression that defines one or more attributes with the data type and the value of each attribute.
        public let otherAttributes: [String: AttributeValue]?
        ///  The name of the group.
        public let samAccountName: String
        ///  The type of update to be performed. If no value exists for the attribute, use ADD. Otherwise, use REPLACE to change an attribute value or REMOVE to clear the attribute value.
        public let updateType: UpdateType?

        @inlinable
        public init(clientToken: String? = UpdateGroupRequest.idempotencyToken(), directoryId: String, groupScope: GroupScope? = nil, groupType: GroupType? = nil, otherAttributes: [String: AttributeValue]? = nil, samAccountName: String, updateType: UpdateType? = nil) {
            self.clientToken = clientToken
            self.directoryId = directoryId
            self.groupScope = groupScope
            self.groupType = groupType
            self.otherAttributes = otherAttributes
            self.samAccountName = samAccountName
            self.updateType = updateType
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encodeIfPresent(self.clientToken, forKey: .clientToken)
            request.encodeQuery(self.directoryId, key: "DirectoryId")
            try container.encodeIfPresent(self.groupScope, forKey: .groupScope)
            try container.encodeIfPresent(self.groupType, forKey: .groupType)
            try container.encodeIfPresent(self.otherAttributes, forKey: .otherAttributes)
            try container.encode(self.samAccountName, forKey: .samAccountName)
            try container.encodeIfPresent(self.updateType, forKey: .updateType)
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 128)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: "^[\\x00-\\x7F]+$")
            try self.validate(self.directoryId, name: "directoryId", parent: name, pattern: "^d-[0-9a-f]{10}$")
            try self.otherAttributes?.forEach {
                try validate($0.key, name: "otherAttributes.key", parent: name, max: 63)
                try validate($0.key, name: "otherAttributes.key", parent: name, min: 1)
                try validate($0.key, name: "otherAttributes.key", parent: name, pattern: "^[A-Za-z*][A-Za-z-*]*$")
                try $0.value.validate(name: "\(name).otherAttributes[\"\($0.key)\"]")
            }
            try self.validate(self.otherAttributes, name: "otherAttributes", parent: name, max: 25)
            try self.validate(self.otherAttributes, name: "otherAttributes", parent: name, min: 1)
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, max: 64)
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, min: 1)
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, pattern: "^[^:;|=+\"*?<>/\\\\,\\[\\]@]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "ClientToken"
            case groupScope = "GroupScope"
            case groupType = "GroupType"
            case otherAttributes = "OtherAttributes"
            case samAccountName = "SAMAccountName"
            case updateType = "UpdateType"
        }
    }

    public struct UpdateGroupResult: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateUserRequest: AWSEncodableShape {
        ///  A unique and case-sensitive identifier that you provide to make sure the idempotency of the request, so multiple identical calls have the same effect as one single call.  A client token is valid for 8 hours after the first request that uses it completes. After 8 hours, any request with the same client token is treated as a new request. If the request succeeds, any future uses of that token will be idempotent for another 8 hours.  If you submit a request with the same client token but change one of the other parameters within the 8-hour idempotency window, Directory Service Data returns an ConflictException.   This parameter is optional when using the CLI or SDK.
        public let clientToken: String?
        ///  The identifier (ID) of the directory that's associated with the user.
        public let directoryId: String
        ///  The email address of the user.
        public let emailAddress: String?
        ///  The first name of the user.
        public let givenName: String?
        ///  An expression that defines one or more attribute names with the data type and value of each attribute. A key is an attribute name, and the value is a list of maps. For a list of supported attributes, see Directory Service Data Attributes.   Attribute names are case insensitive.
        public let otherAttributes: [String: AttributeValue]?
        ///  The name of the user.
        public let samAccountName: String
        ///  The last name of the user.
        public let surname: String?
        ///  The type of update to be performed. If no value exists for the attribute, use ADD. Otherwise, use REPLACE to change an attribute value or REMOVE to clear the attribute value.
        public let updateType: UpdateType?

        @inlinable
        public init(clientToken: String? = UpdateUserRequest.idempotencyToken(), directoryId: String, emailAddress: String? = nil, givenName: String? = nil, otherAttributes: [String: AttributeValue]? = nil, samAccountName: String, surname: String? = nil, updateType: UpdateType? = nil) {
            self.clientToken = clientToken
            self.directoryId = directoryId
            self.emailAddress = emailAddress
            self.givenName = givenName
            self.otherAttributes = otherAttributes
            self.samAccountName = samAccountName
            self.surname = surname
            self.updateType = updateType
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encodeIfPresent(self.clientToken, forKey: .clientToken)
            request.encodeQuery(self.directoryId, key: "DirectoryId")
            try container.encodeIfPresent(self.emailAddress, forKey: .emailAddress)
            try container.encodeIfPresent(self.givenName, forKey: .givenName)
            try container.encodeIfPresent(self.otherAttributes, forKey: .otherAttributes)
            try container.encode(self.samAccountName, forKey: .samAccountName)
            try container.encodeIfPresent(self.surname, forKey: .surname)
            try container.encodeIfPresent(self.updateType, forKey: .updateType)
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 128)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: "^[\\x00-\\x7F]+$")
            try self.validate(self.directoryId, name: "directoryId", parent: name, pattern: "^d-[0-9a-f]{10}$")
            try self.validate(self.emailAddress, name: "emailAddress", parent: name, max: 256)
            try self.validate(self.emailAddress, name: "emailAddress", parent: name, min: 1)
            try self.validate(self.givenName, name: "givenName", parent: name, max: 64)
            try self.validate(self.givenName, name: "givenName", parent: name, min: 1)
            try self.otherAttributes?.forEach {
                try validate($0.key, name: "otherAttributes.key", parent: name, max: 63)
                try validate($0.key, name: "otherAttributes.key", parent: name, min: 1)
                try validate($0.key, name: "otherAttributes.key", parent: name, pattern: "^[A-Za-z*][A-Za-z-*]*$")
                try $0.value.validate(name: "\(name).otherAttributes[\"\($0.key)\"]")
            }
            try self.validate(self.otherAttributes, name: "otherAttributes", parent: name, max: 25)
            try self.validate(self.otherAttributes, name: "otherAttributes", parent: name, min: 1)
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, max: 20)
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, min: 1)
            try self.validate(self.samAccountName, name: "samAccountName", parent: name, pattern: "^[\\w\\-.]+$")
            try self.validate(self.surname, name: "surname", parent: name, max: 64)
            try self.validate(self.surname, name: "surname", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "ClientToken"
            case emailAddress = "EmailAddress"
            case givenName = "GivenName"
            case otherAttributes = "OtherAttributes"
            case samAccountName = "SAMAccountName"
            case surname = "Surname"
            case updateType = "UpdateType"
        }
    }

    public struct UpdateUserResult: AWSDecodableShape {
        public init() {}
    }

    public struct User: AWSDecodableShape {
        ///  The distinguished name of the object.
        public let distinguishedName: String?
        ///  The email address of the user.
        public let emailAddress: String?
        ///  Indicates whether the user account is active.
        public let enabled: Bool?
        ///  The first name of the user.
        public let givenName: String?
        ///  An expression that includes one or more attributes, data types, and values of a user.
        public let otherAttributes: [String: AttributeValue]?
        ///  The name of the user.
        public let samAccountName: String
        ///  The unique security identifier (SID) of the user.
        public let sid: String?
        ///  The last name of the user.
        public let surname: String?
        ///  The UPN that is an internet-style login name for a user and based on the internet standard RFC 822. The UPN is shorter than the distinguished name and easier to remember.
        public let userPrincipalName: String?

        @inlinable
        public init(distinguishedName: String? = nil, emailAddress: String? = nil, enabled: Bool? = nil, givenName: String? = nil, otherAttributes: [String: AttributeValue]? = nil, samAccountName: String, sid: String? = nil, surname: String? = nil, userPrincipalName: String? = nil) {
            self.distinguishedName = distinguishedName
            self.emailAddress = emailAddress
            self.enabled = enabled
            self.givenName = givenName
            self.otherAttributes = otherAttributes
            self.samAccountName = samAccountName
            self.sid = sid
            self.surname = surname
            self.userPrincipalName = userPrincipalName
        }

        private enum CodingKeys: String, CodingKey {
            case distinguishedName = "DistinguishedName"
            case emailAddress = "EmailAddress"
            case enabled = "Enabled"
            case givenName = "GivenName"
            case otherAttributes = "OtherAttributes"
            case samAccountName = "SAMAccountName"
            case sid = "SID"
            case surname = "Surname"
            case userPrincipalName = "UserPrincipalName"
        }
    }

    public struct UserSummary: AWSDecodableShape {
        /// Indicates whether the user account is active.
        public let enabled: Bool
        /// The first name of the user.
        public let givenName: String?
        /// The name of the user.
        public let samAccountName: String
        ///  The unique security identifier (SID) of the user.
        public let sid: String
        /// The last name of the user.
        public let surname: String?

        @inlinable
        public init(enabled: Bool, givenName: String? = nil, samAccountName: String, sid: String, surname: String? = nil) {
            self.enabled = enabled
            self.givenName = givenName
            self.samAccountName = samAccountName
            self.sid = sid
            self.surname = surname
        }

        private enum CodingKeys: String, CodingKey {
            case enabled = "Enabled"
            case givenName = "GivenName"
            case samAccountName = "SAMAccountName"
            case sid = "SID"
            case surname = "Surname"
        }
    }

    public struct ValidationException: AWSErrorShape {
        public let message: String?
        ///  Reason the request failed validation.
        public let reason: ValidationExceptionReason?

        @inlinable
        public init(message: String? = nil, reason: ValidationExceptionReason? = nil) {
            self.message = message
            self.reason = reason
        }

        private enum CodingKeys: String, CodingKey {
            case message = "Message"
            case reason = "Reason"
        }
    }
}

// MARK: - Errors

/// Error enum for DirectoryServiceData
public struct DirectoryServiceDataErrorType: AWSErrorType {
    enum Code: String {
        case accessDeniedException = "AccessDeniedException"
        case conflictException = "ConflictException"
        case directoryUnavailableException = "DirectoryUnavailableException"
        case internalServerException = "InternalServerException"
        case resourceNotFoundException = "ResourceNotFoundException"
        case throttlingException = "ThrottlingException"
        case validationException = "ValidationException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize DirectoryServiceData
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    ///  You don't have permission to perform the request or access the directory. It can also occur when the DirectoryId doesn't exist or the user, member, or group might be outside of your organizational unit (OU).  Make sure that you have the authentication and authorization to perform the action. Review the directory information in the request, and make sure that the object isn't outside of your OU.
    public static var accessDeniedException: Self { .init(.accessDeniedException) }
    ///  This error will occur when you try to create a resource that conflicts with an existing object. It can also occur when adding a member to a group that the member is already in. This error can be caused by a request sent within the 8-hour idempotency window with the same client token but different input parameters. Client tokens should not be re-used across different requests. After 8 hours, any request with the same client token is treated as a new request.
    public static var conflictException: Self { .init(.conflictException) }
    ///  The request could not be completed due to a problem in the configuration or current state of the specified directory.
    public static var directoryUnavailableException: Self { .init(.directoryUnavailableException) }
    ///  The operation didn't succeed because an internal error occurred. Try again later.
    public static var internalServerException: Self { .init(.internalServerException) }
    ///  The resource couldn't be found.
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    ///  The limit on the number of requests per second has been exceeded.
    public static var throttlingException: Self { .init(.throttlingException) }
    ///  The request isn't valid. Review the details in the error message to update the invalid parameters or values in your request.
    public static var validationException: Self { .init(.validationException) }
}

extension DirectoryServiceDataErrorType: AWSServiceErrorType {
    public static let errorCodeMap: [String: AWSErrorShape.Type] = [
        "AccessDeniedException": DirectoryServiceData.AccessDeniedException.self,
        "DirectoryUnavailableException": DirectoryServiceData.DirectoryUnavailableException.self,
        "ThrottlingException": DirectoryServiceData.ThrottlingException.self,
        "ValidationException": DirectoryServiceData.ValidationException.self
    ]
}

extension DirectoryServiceDataErrorType: Equatable {
    public static func == (lhs: DirectoryServiceDataErrorType, rhs: DirectoryServiceDataErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension DirectoryServiceDataErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
